import dataService, {
    Between,
    LessThan,
    LessThanOrEqual,
    MoreThan,
    MoreThanOrEqual
} from './data-service'
import {
    syncApi,
    syncStage,
    syncResources,
    getLatestResourceVersion,
    createResourceVersion,
    release,
    grantPermissions,
    decodeToken
} from '@bkui/apigateway-nodejs-sdk'
import openApiJson from '../conf/open-api.json'
import token from '../conf/token'
const apiName = 'lesscode-1042qgdemo'

// 基于 conditions 获取查询数据
export const parseConditions = (conditions) => {
    const {
        connector,
        expressions
    } = conditions
    const where = connector === 'or' ? [] : {}
    const getExpression = ({
        key,
        type,
        condition,
        value
    }) => {
        const whereCondition = {
            [key]: value
        }
        if (type === 'system' && value === '{{date}}') {
            whereCondition[key] = new Date()
        }
        switch (condition) {
            case '>':
                whereCondition[key] = MoreThan(whereCondition[key])
                break
            case '>=':
                whereCondition[key] = MoreThanOrEqual(whereCondition[key])
                break
            case '<':
                whereCondition[key] = LessThan(whereCondition[key])
                break
            case '<=':
                whereCondition[key] = LessThanOrEqual(whereCondition[key])
                break
        }
        return whereCondition
    }
    expressions.forEach((expression) => {
        if (connector === 'or') {
            where.push(getExpression(expression))
        } else {
            Object.assign(
                where,
                getExpression(expression)
            )
        }
    })
    return where
}

// 通过 key 过滤数据
export const filterTableDataWithKeys = async (tableName, query, page, pageSize, fields) => {
    // 时间类型的转换为区间
    const { columns } = dataService.getTableMetadata(tableName)
    Object.keys(query).forEach((key) => {
        const column = columns.find(column => column.propertyName === key)
        const val = query[key]
        if (Array.isArray(val) && val.length === 2 && column?.type === 'datetime') {
            query[key] = Between(val[0], val[1])
        }
    })
    const result = await dataService.get({
        tableFileName: tableName,
        page,
        pageSize,
        query
    })
    // 过滤
    if (fields && fields.length) {
        result.list = result.list.map((item) => {
            return fields.reduce((acc, cur) => {
                acc[cur] = item[cur]
                return acc
            }, {})
        })
    }
    return result
}

// 通过条件过滤数据
export const filterTableDataWithConditions = async (conditions, tableName, group, field) => {
    const query = parseConditions(conditions)
    let { list } = await dataService.get({
        tableFileName: tableName,
        query
    })
    // 聚合
    if (group) {
        const groupList = []
        list.forEach((item) => {
            const index = groupList.findIndex((x) => (x[group] === item[group]))
            if (index < 0) {
                groupList.push(item)
            }
        })
        list = groupList
    }
    return list.map((item) => ({
        id: item.id,
        [field]: item[field]
    }))
}

// ApiGateWay 上给 ITSM 授权
export const grantApiGWPermissionForApps = async () => {
    // dev 模式下不创建网关
    if (process.env.NODE_ENV === 'development') return Promise.resolve()

    // 同步网关
    await syncApi(
        apiName,
        {
            description: 'generated by bk-lesscode',
            maintainers: ['3210921043X'],
            is_public: false,
            user_auth_type: global.BKPAAS_ENGINE_REGION
        },
        token,
        'prod'
    )
    console.log('应用网关创建完成')
    // 同步环境
    const accessUrl = JSON.parse(process.env.BKPAAS_DEFAULT_PREALLOCATED_URLS)[process.env.BKPAAS_ENVIRONMENT]
    const urlObject = new URL(accessUrl)
    let pathname = urlObject.pathname
    if (pathname.startsWith('/')) {
        pathname = pathname.slice(1)
    }
    if (pathname && !pathname.endsWith('/')) {
        pathname = pathname + '/'
    }
    await syncStage(
        apiName,
        {
            name: process.env.BKPAAS_ENVIRONMENT,
            vars: {
                subpath: pathname
            },
            proxy_http: {
                timeout: 60,
                upstreams: {
                    loadbalance: 'roundrobin',
                    hosts: [
                        {
                            host: urlObject.origin,
                            weight: '100'
                        }
                    ]
                }
            }
        },
        token,
        'prod'
    )
    console.log(`创建${process.env.BKPAAS_ENVIRONMENT}环境完成`)

    // 同步资源
    await syncResources(
        apiName,
        {
            content: JSON.stringify(openApiJson)
        },
        token,
        'prod'
    )
    console.log('网关api资源同步完成')

    // 获取网关最新版本
    const { data = {} } = await getLatestResourceVersion(apiName, token, 'prod')
    const version = (data.version || '0.0.0').replace(/.$/, (x) => {
        return +x + 1
    })
    console.log('开始发布网关')
    try {
        // 创建资源版本
        await createResourceVersion(
            apiName,
            {
                version,
                title: 'create new version'
            },
            token,
            'prod'
        )
        console.log('创建网关api资源版本完成')
        // 发布版本
        await release(
            apiName,
            {
                version,
                stage_names: [process.env.BKPAAS_ENVIRONMENT],
                comment: 'release new version'
            },
            token,
            'prod'
        )
        console.log('网关api版本发布完成')
        // 网关为应用主动授权
        console.log(`itsm appCode名称${global.ITSM_APP_CODE}`)
        await grantPermissions(
            apiName,
            {
                target_app_code: global.ITSM_APP_CODE,
                grant_dimension: 'api'
            },
            token,
            'prod'
        )
        console.log(`为itsm主动授权完成，appCode为${global.ITSM_APP_CODE}`)

        // 为bkvision主动授权接口权限
        // await grantPermissions(
        //     apiName,
        //     {
        //         target_app_code: 'bkvision',
        //         grant_dimension: 'api'
        //     },
        //     token,
        //     'prod'
        // )
        // console.log(`为bkvision主动授权完成`)
    } catch (e) {
        console.log('发布网关失败', e.message || e)
    }
}

export const getUserFromApiGW = async (jwt) => {
    const { user } = await decodeToken(apiName, jwt, token, 'prod')
    console.log('--------------->jwt username', user)
    if (!user) {
        throw new Error('未解析到用户名，请修改后再试')
    }
    return user
}
